﻿<!---
	3 phases:
		create bind
		call the server
		do something with the result
--->

<cfparam default="body" name="attributes.selector">
<cfparam default="" name="attributes.attribute">
<cfparam default="change" name="attributes.event">
<cfparam default="" name="attributes.cfc">
<cfparam default="" name="attributes.callback">
<cfparam default="body" name="attributes.target">

<cfif NOT len(attributes.attribute)>
	<cfset theseAttributes = attributes.attribute>
<cfelse>
	<cfset theseAttributes = "value">
</cfif>

<cftry>
	<cfset methodName = listLast(attributes.cfc, ".")>
	<cfset componentName = replaceNoCase(attributes.cfc, ".#methodName#", "")>
	<cfset componentName = listChangeDelims(componentName, "/", ".")>
	<cfset serviceURL = application.URL & componentName & ".cfc?method=" & methodName>

	<cfcatch>
		<cfthrow message="cf_bind failed" detail="There was a problem with the cfc attribute.  It must be of the form: com.ponent.name.method">
	</cfcatch>
</cftry>

<cfset methodInfo = getMetadata(evaluate('createObject("component", componentName).#methodName#'))>
<cfset returnFormat = methodInfo.returnFormat>
<cfset parameterName = methodInfo.parameters>
<cfset params = arrayNew(1)>
<cfloop array="#methodInfo.parameters#" index="I">
	<cfset arrayAppend(params, I.name)>
</cfloop>

<cfif arraylen(methodInfo.parameters) NEQ listLen(attributes.attribute, " ")>
	<cfthrow message="not enough attributes" detail="The number of attributes provided must match the number of method arguments.  CFC = #attributes.cfc#; expected arguments = #serializeJSON(params)#; attributes = #attributes.attribute#">
</cfif>

<cfset bindID = hash(now())>

<cfsavecontent variable="jsReady">
	<cfoutput>
		<cfif len(attributes.attribute)>
			var args#bindID# = eval(#serializeJSON(params)#);
			var attr#bindID#;
			var attrName#bindID# = eval(#serializeJSON(listToArray(theseAttributes, " "))#);
			var param#bindID#;
		</cfif>

		$("#attributes.selector#").bind("#attributes.event#", function() {
			<cfif len(attributes.attribute)>
				attr#bindID# = new Array();
				param#bindID# = {};
				for (var I = 0, L = attrName#bindID#.length; I < L; I++) {
					attr#bindID#[I] = $("#attributes.selector#").attr(attrName#bindID#[I]);
				}
				/*
				for (var I = 0, L = attr#bindID#.length; I < L; I++) {
					param#bindID#[I] = args#bindID#[I] + ":" + attr#bindID#[I];
				}
				param#bindID# = "{" + param#bindID#.join(",") + "}";
				*/
				for (var I = 0, L = attr#bindID#.length; I < L; I++) {
					param#bindID#[args#bindID#[I]] =  attr#bindID#[I];
				}
			</cfif>

			<cfif isDefined("attributes.cfc") AND listLen(attributes.cfc, ".")>
				$.post("#serviceURL#",
					<cfif len(attributes.attribute)>
						param#bindID#,
					</cfif>
					function(result) {
						<cfif isDefined("attributes.target") AND len(trim(attributes.target))>
							if (typeof(result) == "string") {
								$("#attributes.target#").html(result);
							} else {
								for (X in result) {
									$("#attributes.target#").attr(X, result[X]);
									$("#attributes.target#").css(X, result[X]);
								}
							}
						<cfelseif isDefined("attributes.callback")>
							this.call(#attributes.callback#, result);
						</cfif>
					}
				);
			<cfelseif isDefined("attributes.callback") AND len(trim(attributes.callback))>
				this.apply(#attributes.callback#, attr#bindID#);
			</cfif>
		});
	</cfoutput>
</cfsavecontent>

<cfset arrayAppend(request.readyFunctions, jsReady)>